DevelopersIO 2023 にて「AWS Lambdaは俺が作った」というタイトルで発表しました #devio2023

DevelopersIO 2023 にて「AWS Lambdaは俺が作った」というタイトルで発表しました #devio2023

2023年7月7日・7月6日に開催されたDevelopersIO 2023、2023年7月19日に開催されたDevelopersIO 2023大阪のセッション「AWS Lambdaは俺が作った」の登壇ブログです
Clock Icon2023.07.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CX事業本部@大阪の岩田です。

2023年7月7日・7月6日に開催されたDevelopersIO 2023、2023年7月19日に開催されたDevelopersIO 2023大阪にて「AWS Lambdaは俺が作った」というテーマで登壇させて頂きました。

登壇資料

登壇資料はこちらです

「AWS Lambdaは俺が作った!!」とは?

まずセッションタイトルの意味するところについての説明です。皆さんお分かりだとは思いますが、私は実際にLamdbaを作ったわけではありません。

AWS LambdaはFirecrackerによって支えられている → Firecrackerを作った人はAWS Lambdaを作った人と言えるのではないか? → FirecrackerはOSSであり、誰でもコントリビュート可能 → Firecrackerにコントリビュートすれば「AWS Lambdaは俺が作った!!」と言っても良いのではないか?

というこじつけによってこのセッションタイトルが生まれました。

Firecracker開発の経緯

Lambdaというサービスがローンチされた当初、Firecrackerはまだ存在しませんでした。EC2モデルと呼ばれていた当時のアーキテクチャを振り返りつつ、なぜFirecrackerが必要とされたのか?Firecracker開発の経緯について振り返りました。

EC2モデルではゲストOSをAWSアカウントの境界とし、ゲストOS上に複数のLambda Functionをデプロイする構成でした。コンテナレベルではなくゲストOSレベルでAWSアカウントの境界を設けているのはセキュリティレベルを高く保つためです。

一方でこのアプローチはワークロードの集約率が上がり辛いという欠点がありました。これらの問題を解決するために、セキュリティレベルが高く、オーバーヘッドが小さいVMMが必要とされました。これがFirecracker開発の経緯です。

Firecrackerによってもたらされたもの

Lambdaの実行基盤がFirecrackerに置き換えられたことで、高いセキュリティレベルを担保しつつ効率よく大量のワークロードを集約することが可能になりました。

2019年1月にFargateの大幅値下げがありましたが、実はこれの裏でもFirecrackerが活躍しています。

Firecrackerプロジェクト概要

FirecrackerはCrosVMからフォークしてスタートしています。フォークしてからFirecrackerとCrosVMはそれぞれ開発を続けていましたが、両者にはいくつかの共通点があり、お互いの成果物をお互いに取り込むといったことがしばしば起きていたようです。そこで両者の共通部分を抜き出して、RustでVMMを実装する際に利用できるビルディングブロックを提供するRust-vmmというプロジェクトが発足しました。これにより、FirecrackerはRust-vmmのクレートに依存するようになりました。

CrosVMとFirecracker以外のRust-vmmユーザーとしてはIntelのCloud Hypervisorが挙げられます。Cloud HypervisorはCrosVM・Firecrackerの実装に基づいており、Rust-vmmを利用していますが、コンテナやサーバーレスのワークロードに限定せず、幅広くクラウドのワークロードを対象としている点でコンセプトが異なります。

コントリビューション実績の紹介

筆者のコントリビューション実績として以下を紹介しました

エラー用のenumがthiserror::Errorを使うように修正

簡単に言うと、以下のようなコードがあるので...

#[derive(Debug)]
pub enum LoggerError {
    /// Initialization Error.
    Init(init::Error),
}

impl fmt::Display for LoggerError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let printable = match *self {
            LoggerError::Init(ref err) => format!("Logger initialization failure: {}", err),
        };
        write!(f, "{}", printable)
    }
}

以下のように書き換える

#[derive(Debug, thiserror::Error)]
pub enum LoggerError {
    /// Initialization Error.
    #[error("Logger initialization failure: {0}")]
    Init(init::Error),
}

というだけの内容です。

以下のブログで紹介されている内容そのままですね。

ドキュメントの記述ミスを修正

こちらはタイトルそのままです。dockerイメージのタグ誤りを修正しました。

PythonのコードフォーマッターBlackの除外ルール調整

Firecracker自体はRustで開発されていますが、IntegrationテストはPythonで書かれています。このテストコードはPythonのコードフォーマッタであるblackでフォーマットされているのですが、integration_tests/build 配下のコードがフォーマットされていなかったため、対策を組み込みました。

integrationテストの重複コード削除

こちらもintegrationテスト関連です。テスト実行環境のLinuxカーネルのバージョンを取得する関数get_kernel_versionが2箇所で重複定義されていたため、issueを起票しつつ重複を解消したという内容です。

1つ目のget_kernel_versionは以下のコードで

def get_kernel_version(level=2):
    """Return the current kernel version in format `major.minor.patch`."""
    linux_version = platform.release()
    actual_level = 0
    for idx, char in enumerate(linux_version):
        if char == ".":
            actual_level += 1
        if actual_level > level or (not char.isdigit() and char != "."):
            linux_version = linux_version[0:idx]
            break
    return linux_version

2つ目のget_kernel_versionは以下のコードでした。この2つ目のget_kernel_versionの定義を削除してリファクタリングしました。

def get_kernel_version(level):
    """Return the current kernel version in format `major.minor.patch`."""
    linux_version = platform.release()
    # 5.15.0-56-generic
    # major, minor, patch
    mmp = linux_version.split("-")[0].split(".")
    return ".".join(mmp[:level])

これらコントリビューション実績の詳細を見て頂ければ分かるのですが、実はこれらのコントリビューション実績は簡単な内容ばかりです。このセッションで一番伝えたかった部分なのですが、FirecrackerにコントリビュートするためにはRustの知識もVMMの知識も必須ではありません。やる気さえあればコントリビュートは可能なので、是非みなさんもコントリビュートを狙って見て下さい。

コントリビューション手順

実際にコントリビュートするにあたって役に立つであろう知識をいくつかご紹介しました。

開発環境構築

まずは開発環境の構築が必要になります。FiracrackerはKVMを利用するため、開発環境にも多少の制約があります。開発環境としていくつかのパターンをご紹介しました。

  • 物理マシンを使う
    • 適当なマシンが余っていれば...
    • Windows/Macとのドゥアルブートも選択肢に
  • パブリッククラウドを使う
    • EC2 on AWS
    • ベアメタルインスタンスが必須なのでコストがネック
    • Compute Engine on Google Cloud
    • Nested Virtualizationに対応したインスタンスが利用可能
    • 個人的オススメ
  • Nested Virtualizationに対応した仮想化ソフトウェアを使う
    • VMware Fusion
    • Firecrackerのドキュメントにも記載されているが有償なのがネック
    • Virtual Box
    • Firecrackerリリース当時はNested Virtualizationに未対応だったが、今は対応している。無償なので気軽に試しやすい

オススメツール

Firecrackerの開発には開発用のコンテナイメージを利用するのですが、開発用のコンテナイメージとVS Codeを連携させるためのExtensionと具体的な設定ファイルの例を紹介しました。この辺をうまく設定してもらうとVS Codeの入力補完等の恩恵が受けられるので、生産性高く開発が進められるようになります。

issue探し

開発環境が整ったらコントリビューションできそうなissueを探しましょう。ただし、「Good first issue」のラベルが付与されたissueは大体PR作成済み or マージ済みです。今から新たにissueを探すのであれば、以下のissueをとっかかりにtodoコメントが入っている箇所からコントリビューションできそうな箇所を探すのが良いのではないでしょうか。

https://github.com/firecracker-microvm/firecracker/issues/3273

開発時のTIPS

実際に開発を進めていく上でのTIPSをいくつか紹介しました。

  • ./tools/devtoolで便利コマンドを実行
    • 便利なので覚えましょう
  • ユニットテストもpytest経由で実行
    • cargo testは落ちます
  • コミット時の注意事項
    • git commitには-sを付ける
    • コミット後はgitlintでコミットメッセージのチェック
  • カバレッジの調整
    • CIがコケたら必要に応じて調整しましょう

まとめ

この発表で伝えたかった一番のポイントは

「RustやVMMの知識が無くてもFirecrackerにコントリビュートすることは可能!」

ということです。この発表をきっかけにFirecrackerにコントリビュートできた!という人が誰か1人でも現れてくれたら発表者としては非常に嬉しいです。是非挑戦してみて下さい。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.